;/*
; * Copyright (c) 2022, IMMORTA Inc.
; * All rights reserved.
; *
; * Redistribution and use in source and binary forms, with or without modification,
; * are permitted provided that the following conditions are met:
; *
; * - Redistributions of source code must retain the above copyright notice, this list
; *   of conditions and the following disclaimer.
; *
; * - Redistributions in binary form must reproduce the above copyright notice, this
; *   list of conditions and the following disclaimer in the documentation and/or
; *   other materials provided with the distribution.
; *
; * - Neither the name of IMMORTA Inc. nor the names of its
; *   contributors may be used to endorse or promote products derived from this
; *   software without specific prior written permission.
; *
; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
; * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
; * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
; * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
; */

  .syntax unified
  .cpu cortex-m4
  .fpu softvfp
  .thumb

.global  g_pfnVectors
.global  g_bootVectors
.global  Default_Handler
.global __Vectors
.global __BootHeader

/* start address for the initialization values of the .data section.
defined in linker script */
.word  _sidata
/* start address for the .data section. defined in linker script */
.word  _sdata
/* end address for the .data section. defined in linker script */
.word  _edata
/* start address for the .bss section. defined in linker script */
.word  _sbss
/* end address for the .bss section. defined in linker script */
.word  _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */

/**
 * @brief  This is the code that gets called when the processor first
 *          starts execution following a reset event. Only the absolutely
 *          necessary set is performed, after which the application
 *          supplied main() routine is called.
 * @param  None
 * @retval : None
*/

  .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler:

/*Mask interrupts*/
  CPSID   I

  LDR R1, = 0x4001002C
  LDR R0, = 0x5A1234A5
  STR R0, [R1]

  LDR R1, = 0x40010020
  LDR R0, = 0xFFFFFFFF
  STR R0, [R1]

  LDR R1, = 0x40010024
  LDR R0, = 0xFFFFFFFF
  STR R0, [R1]

  LDR R1, = 0x40000000
  LDR R0, = 0x34C
  STR R0, [R1]

/* Initialize the stack pointer */
  LDR R0, = _estack
  MOV R13, R0

/*Errata*/
  LDR R1, = 0x4000E800
  LDR R0, = 0x00000709
  STR R0, [R1]

  LDR R1, = 0x4000E804
  LDR R0, = 0x00000709
  STR R0, [R1]

  LDR R1, = 0x4000E414
  LDR R0, = 0x00000709
  STR R0, [R1]

  LDR R1, = 0x4000E02C
  LDR R0, = 0x0000070A
  STR R0, [R1]

  LDR R1, = 0x4000E010
  LDR R0, = 0x00000709
  STR R0, [R1]

  LDR R1, = 0x4000E410
  LDR R0, = 0x0000070A
  STR R0, [R1]

  LDR R1, = 0x4000000C
  LDR R0, = 0xB2063001
  STR R0, [R1]

  LDR R1, = 0x40002034
  LDR R0, = 0xE0402008
  STR R0, [R1]

  LDR R1, = 0x4000000C
  LDR R0, = 0xB2063000
  STR R0, [R1]

/*Init ECC RAM*/
  LDR     R1, = _Sram_Start_Addr
  LDR     R2, = _Sram_End_Addr
  SUBS    R2, R1
  SUBS    R2, #1
  BLE LE0

  MOVS    R0, #0
  MOVS    R3, #4
LE1:
  STR R0, [R1]
  ADD R1, R1, R3
  SUBS R2, #4
  BGE LE1
LE0:
  NOP

/* Copy the data segment initializers from flash to SRAM */
  movs  r1, #0
  b  LoopCopyDataInit

CopyDataInit:
  ldr  r3, =_sidata
  ldr  r3, [r3, r1]
  str  r3, [r0, r1]
  adds  r1, r1, #4

LoopCopyDataInit:
  ldr  r0, =_sdata
  ldr  r3, =_edata
  adds  r2, r0, r1
  cmp  r2, r3
  bcc  CopyDataInit
  ldr  r2, =_sbss
  b  LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
  movs  r3, #0
  str  r3, [r2]
  movs  r3, #4
  add r2, r2, r3

LoopFillZerobss:
  ldr  r3, = _ebss
  cmp  r2, r3
  bcc  FillZerobss

/*Unmask interrupts*/
  CPSIE   I

/* Call the clock system intitialization function.*/
  bl  SystemInit

//;  ldr     R0, =0x20080014
//;  ldr     R1, =0xFFFF
//;  strh    R1, [R0]

//;  ldr     R0, =0x20080044
//;  ldr     R1, =0xFFFF
//;  strh    R1, [R0]

//;  ldr     R0, =0x20080074
//;  ldr     R1, =0x3FF
//;  strh    R1, [R0]

/* Call static constructors */
/*    bl __libc_init_array    */
/* Call the application's entry point.'*/
  bl  main
  bx  lr
.size  Reset_Handler, .-Reset_Handler

/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 * @param  None
 * @retval None
*/
    .section  .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
  .size  Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M4F. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
*******************************************************************************/
  .section  .isr_vector,"a",%progbits
  .type  g_pfnVectors, %object
  .size  g_pfnVectors, .-g_pfnVectors

g_pfnVectors:
        .word      _estack
        .word      Reset_Handler             /*Reset Handler*/
        .word      NMI_Handler               /*NMI Handler*/
        .word      HardFault_Handler         /*Hard Fault Handler*/
        .word      MemManage_Handler         /*MPU Fault Handler*/
        .word      BusFault_Handler          /*Bus Fault Handler*/
        .word      UsageFault_Handler        /*Usage Fault Handler*/
        .word      0                         /*Reserved*/
        .word      0                         /*Reserved*/
        .word      0                         /*Reserved*/
        .word      0                         /*Reserved*/
        .word      SVC_Handler               /*SVCall Handler*/
        .word      DebugMon_Handler          /*Debug Monitor Handler*/
        .word      0                         /*Reserved*/
        .word      PendSV_Handler            /*PendSV Handler*/
        .word      SysTick_Handler           /*SysTick Handler*/

/* External interrupts */
        .word      WDG_IRQHandler            /*Internal Watch Dog*/
        .word      ERM_Error_IRQHandler      /*ERM Error*/
        .word      LVD_IRQHandler            /*Low Voltage Detection*/
        .word      CLOCK_Fault_IRQHandler    /*Clock Fault*/
        .word      DMA_Channel0_IRQHandler   /*DMA Channel 0*/
        .word      DMA_Channel1_IRQHandler   /*DMA Channel 1*/
        .word      DMA_Channel2_IRQHandler   /*DMA Channel 2*/
        .word      DMA_Channel3_IRQHandler   /*DMA Channel 3*/
        .word      DMA_Channel4_IRQHandler   /*DMA Channel 4*/
        .word      DMA_Channel5_IRQHandler   /*DMA Channel 5*/
        .word      DMA_Channel6_IRQHandler   /*DMA Channel 6*/
        .word      DMA_Channel7_IRQHandler   /*DMA Channel 7*/
        .word      Reserved0_IRQHandler      /*Reserved0*/
        .word      Reserved1_IRQHandler      /*Reserved1*/
        .word      Reserved2_IRQHandler      /*Reserved2*/
        .word      Reserved3_IRQHandler      /*Reserved3*/
        .word      GPIOA_IRQHandler          /*GPIOA*/
        .word      GPIOB_IRQHandler          /*GPIOB*/
        .word      GPIOC_IRQHandler          /*GPIOC*/
        .word      GPIOD_IRQHandler          /*GPIOD*/
        .word      GPIOE_IRQHandler          /*GPIOE*/
        .word      Reserved4_IRQHandler      /*Reserved4*/
        .word      RTC_IRQHandler            /*RTC*/
        .word      TIMER0_IRQHandler         /*Timer 0*/
        .word      TIMER1_IRQHandler         /*Timer 1*/
        .word      TIMER2_IRQHandler         /*Timer 2*/
        .word      TIMER3_IRQHandler         /*Timer 3*/
        .word      SPI0_IRQHandler           /*SPI 0*/
        .word      SPI1_IRQHandler           /*SPI 1*/
        .word      SPI2_IRQHandler           /*SPI 2*/
        .word      SPI3_IRQHandler           /*SPI 3*/
        .word      I2C0_IRQHandler           /*I2C 0*/
        .word      I2C1_IRQHandler           /*I2C 1*/
        .word      UART0_IRQHandler          /*UART 0*/
        .word      UART1_IRQHandler          /*UART 1*/
        .word      UART2_IRQHandler          /*UART 2*/
        .word      UART3_IRQHandler          /*UART 3*/
        .word      Reserved5_IRQHandler      /*Reserved5*/
        .word      Reserved6_IRQHandler      /*Reserved6*/
        .word      CAN0_IRQHandler           /*CAN 0*/
        .word      CAN1_IRQHandler           /*CAN 1*/
        .word      CAN2_IRQHandler           /*CAN 2*/
        .word      Reserved7_IRQHandler      /*Reserved7*/
        .word      Reserved8_IRQHandler      /*Reserved8*/
        .word      Reserved9_IRQHandler      /*Reserved9*/
        .word      ADC0_IRQHandler           /*ADC 0*/
        .word      ADC1_IRQHandler           /*ADC 1*/
        .word      CMP0_IRQHandler           /*CMP 0*/
        .word      IPWM0_Channel_IRQHandler  /*IPMW 0 Channel*/
        .word      IPWM0_Overflow_IRQHandler /*IPMW 0 Overflow*/
        .word      IPWM1_Channel_IRQHandler  /*IPMW 1 Channel*/
        .word      IPWM1_Overflow_IRQHandler /*IPMW 1 Overflow*/
        .word      SPWM0_Channel_IRQHandler  /*SPMW 0 Channel*/
        .word      SPWM0_Fault_IRQHandler    /*SPMW 0 Fault*/
        .word      SPWM0_Overflow_IRQHandler /*SPMW 0 Overflow*/
        .word      SPWM1_Channel_IRQHandler  /*SPMW 1 Channel*/
        .word      SPWM1_Fault_IRQHandler    /*SPMW 1 Fault*/
        .word      SPWM1_Overflow_IRQHandler /*SPMW 1 Overflow*/
        .word      SPWM2_Channel_IRQHandler  /*SPMW 2 Channel*/
        .word      SPWM2_Fault_IRQHandler    /*SPMW 2 Fault*/
        .word      SPWM2_Overflow_IRQHandler /*SPMW 2 Overflow*/
        .word      Reserved10_IRQHandler     /*Reserved10*/
        .word      MBOX_IRQHandler           /*HSM Mbox*/
        .word      HSM_IRQHandler            /*HSM Error*/

__Vectors_End = .

__Vectors     =   g_pfnVectors

g_bootVectors:
        .word   0x5AA55AA5;         ;/* Valid boot header marker */
        .word   0x00000000;         ;/* Boot configuration word */
                                    ;/* bit0: soc wdg enable,0-disable,1-enable */
                                    ;/* bit1~bit31: reserved */
        .word   0x00000000;         ;/* 0:HSI 1:HSE+PLL 2:HSI+PLL */
        .word   8000000;            ;/* Frequency of EXTAL/XTAL */
        .word   0;                  ;/* PLL previous divider, 0~63 */
        .word   115;                ;/* PLL feedback divider, 0~4095 */
        .word   2;                  ;/* PLL post divider1, 0~7 */
        .word   1;                  ;/* PLL post divider2, 0~3 */
        .word   0;                  ;/* PLL vcodiv enable, 0~1 */
        .word   0x18000000;         ;/* HSM FW image address */
__BootHeader_End = .

__BootHeader     =   g_bootVectors

/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
   .weak      NMI_Handler
   .thumb_set NMI_Handler,Default_Handler

   .weak      HardFault_Handler
   .thumb_set HardFault_Handler,Default_Handler

   .weak      MemManage_Handler
   .thumb_set MemManage_Handler,Default_Handler

   .weak      BusFault_Handler
   .thumb_set BusFault_Handler,Default_Handler

   .weak      UsageFault_Handler
   .thumb_set UsageFault_Handler,Default_Handler

   .weak      SVC_Handler
   .thumb_set SVC_Handler,Default_Handler

   .weak      DebugMon_Handler
   .thumb_set DebugMon_Handler,Default_Handler

   .weak      PendSV_Handler
   .thumb_set PendSV_Handler,Default_Handler

   .weak      SysTick_Handler
   .thumb_set SysTick_Handler,Default_Handler

   .weak      WDG_IRQHandler
   .thumb_set WDG_IRQHandler,Default_Handler

   .weak      ERM_Error_IRQHandler
   .thumb_set ERM_Error_IRQHandler,Default_Handler

   .weak      LVD_IRQHandler
   .thumb_set LVD_IRQHandler,Default_Handler

   .weak      CLOCK_Fault_IRQHandler
   .thumb_set CLOCK_Fault_IRQHandler,Default_Handler

   .weak      DMA_Channel0_IRQHandler
   .thumb_set DMA_Channel0_IRQHandler,Default_Handler

   .weak      DMA_Channel1_IRQHandler
   .thumb_set DMA_Channel1_IRQHandler,Default_Handler

   .weak      DMA_Channel2_IRQHandler
   .thumb_set DMA_Channel2_IRQHandler,Default_Handler

   .weak      DMA_Channel3_IRQHandler
   .thumb_set DMA_Channel3_IRQHandler,Default_Handler

   .weak      DMA_Channel4_IRQHandler
   .thumb_set DMA_Channel4_IRQHandler,Default_Handler

   .weak      DMA_Channel5_IRQHandler
   .thumb_set DMA_Channel5_IRQHandler,Default_Handler

   .weak      DMA_Channel6_IRQHandler
   .thumb_set DMA_Channel6_IRQHandler,Default_Handler

   .weak      DMA_Channel7_IRQHandler
   .thumb_set DMA_Channel7_IRQHandler,Default_Handler

   .weak      Reserved0_IRQHandler
   .thumb_set Reserved0_IRQHandler,Default_Handler

   .weak      Reserved1_IRQHandler
   .thumb_set Reserved1_IRQHandler,Default_Handler

   .weak      Reserved2_IRQHandler
   .thumb_set Reserved2_IRQHandler,Default_Handler

   .weak      Reserved3_IRQHandler
   .thumb_set Reserved3_IRQHandler,Default_Handler

   .weak      GPIOA_IRQHandler
   .thumb_set GPIOA_IRQHandler,Default_Handler

   .weak      GPIOB_IRQHandler
   .thumb_set GPIOB_IRQHandler,Default_Handler

   .weak      GPIOC_IRQHandler
   .thumb_set GPIOC_IRQHandler,Default_Handler

   .weak      GPIOD_IRQHandler
   .thumb_set GPIOD_IRQHandler,Default_Handler

   .weak      GPIOE_IRQHandler
   .thumb_set GPIOE_IRQHandler,Default_Handler

   .weak      Reserved4_IRQHandler
   .thumb_set Reserved4_IRQHandler,Default_Handler

   .weak      RTC_IRQHandler
   .thumb_set RTC_IRQHandler,Default_Handler

   .weak      TIMER0_IRQHandler
   .thumb_set TIMER0_IRQHandler,Default_Handler

   .weak      TIMER1_IRQHandler
   .thumb_set TIMER1_IRQHandler,Default_Handler

   .weak      TIMER2_IRQHandler
   .thumb_set TIMER2_IRQHandler,Default_Handler

   .weak      TIMER3_IRQHandler
   .thumb_set TIMER3_IRQHandler,Default_Handler

   .weak      SPI0_IRQHandler
   .thumb_set SPI0_IRQHandler,Default_Handler

   .weak      SPI1_IRQHandler
   .thumb_set SPI1_IRQHandler,Default_Handler

   .weak      SPI2_IRQHandler
   .thumb_set SPI2_IRQHandler,Default_Handler

   .weak      SPI3_IRQHandler
   .thumb_set SPI3_IRQHandler,Default_Handler

   .weak      I2C0_IRQHandler
   .thumb_set I2C0_IRQHandler,Default_Handler

   .weak      I2C1_IRQHandler
   .thumb_set I2C1_IRQHandler,Default_Handler

   .weak      UART0_IRQHandler
   .thumb_set UART0_IRQHandler,Default_Handler

   .weak      UART1_IRQHandler
   .thumb_set UART1_IRQHandler,Default_Handler

   .weak      UART2_IRQHandler
   .thumb_set UART2_IRQHandler,Default_Handler

   .weak      UART3_IRQHandler
   .thumb_set UART3_IRQHandler,Default_Handler

   .weak      Reserved5_IRQHandler
   .thumb_set Reserved5_IRQHandler,Default_Handler

   .weak      Reserved6_IRQHandler
   .thumb_set Reserved6_IRQHandler,Default_Handler

   .weak      CAN0_IRQHandler
   .thumb_set CAN0_IRQHandler,Default_Handler

   .weak      CAN1_IRQHandler
   .thumb_set CAN1_IRQHandler,Default_Handler

   .weak      CAN2_IRQHandler
   .thumb_set CAN2_IRQHandler,Default_Handler

   .weak      Reserved7_IRQHandler
   .thumb_set Reserved7_IRQHandler,Default_Handler

   .weak      Reserved8_IRQHandler
   .thumb_set Reserved8_IRQHandler,Default_Handler

   .weak      Reserved9_IRQHandler
   .thumb_set Reserved9_IRQHandler,Default_Handler

   .weak      ADC0_IRQHandler
   .thumb_set ADC0_IRQHandler,Default_Handler

   .weak      ADC1_IRQHandler
   .thumb_set ADC1_IRQHandler,Default_Handler

   .weak      CMP0_IRQHandler
   .thumb_set CMP0_IRQHandler,Default_Handler

   .weak      IPWM0_Channel_IRQHandler
   .thumb_set IPWM0_Channel_IRQHandler ,Default_Handler

   .weak      IPWM0_Overflow_IRQHandler
   .thumb_set IPWM0_Overflow_IRQHandler ,Default_Handler

   .weak      IPWM1_Channel_IRQHandler
   .thumb_set IPWM1_Channel_IRQHandler ,Default_Handler

   .weak      IPWM1_Overflow_IRQHandler
   .thumb_set IPWM1_Overflow_IRQHandler ,Default_Handler

   .weak      SPWM0_Channel_IRQHandler
   .thumb_set SPWM0_Channel_IRQHandler ,Default_Handler

   .weak      SPWM0_Fault_IRQHandler
   .thumb_set SPWM0_Fault_IRQHandler ,Default_Handler

   .weak      SPWM0_Overflow_IRQHandler
   .thumb_set SPWM0_Overflow_IRQHandler ,Default_Handler

   .weak      SPWM1_Channel_IRQHandler
   .thumb_set SPWM1_Channel_IRQHandler ,Default_Handler

   .weak      SPWM1_Fault_IRQHandler
   .thumb_set SPWM1_Fault_IRQHandler ,Default_Handler

   .weak      SPWM1_Overflow_IRQHandler
   .thumb_set SPWM1_Overflow_IRQHandler ,Default_Handler

   .weak      SPWM2_Channel_IRQHandler
   .thumb_set SPWM2_Channel_IRQHandler ,Default_Handler

   .weak      SPWM2_Fault_IRQHandler
   .thumb_set SPWM2_Fault_IRQHandler ,Default_Handler

   .weak      SPWM2_Overflow_IRQHandler
   .thumb_set SPWM2_Overflow_IRQHandler ,Default_Handler

   .weak      Reserved10_IRQHandler
   .thumb_set Reserved10_IRQHandler,Default_Handler

   .weak      MBOX_IRQHandler
   .thumb_set MBOX_IRQHandler ,Default_Handler

   .weak      HSM_IRQHandler
   .thumb_set HSM_IRQHandler  ,Default_Handler

/*******EOF********************************************************************/
